package com.kly.cashmall.services;

import android.text.TextUtils;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.kly.cashmall.utils.data.ObjectUtils;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.RequestBody;

/**
 * Created by zxp on 2021/9/14 0014
 */
public class Params {
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    public static final MediaType FORM = MediaType.parse("multipart/form-data");
    public static final String DEFAULT_DECODE = "UTF-8";

    private HashMap<String, File> fileMap;
    private HashMap<String, Object> formMap = new HashMap<>();

    private MediaType mediaType;

    /**
     * 用于临时存储一个formJson对象,弃用，之后改用extra
     */
    @Deprecated
    private String formJson;

    private HashMap<String, Object> extra;

    public Params putExtra(String key, Object obj) {
        if (extra == null) {
            extra = new HashMap<>();
        }
        extra.put(key, obj);
        return this;
    }

    public Object getExtra(String key) {
        return extra == null ? null : extra.get(key);
    }

    public HashMap<String, Object> getExtraMap() {
        return extra;
    }

    /**
     * 构造POST请求（包括文件）
     */
    public RequestBody buildPostBody() {
        return buildJsonBody();
    }

    protected RequestBody buildJsonBody() {
        JsonObject json = new JsonObject();
        checkFormMap(formMap);
        for (Map.Entry<String, Object> entry : formMap.entrySet()) {
            if (paramsEntrySafe(entry)) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (value instanceof JsonElement) {
                    json.add(key, (JsonElement) value);
                } else if (value instanceof Number) {
                    json.addProperty(key, (Number) value);
                } else if (value instanceof Boolean) {
                    json.addProperty(key, (Boolean) value);
                } else if (value instanceof Character) {
                    json.addProperty(key, (Character) value);
                } else {
                    json.addProperty(key, String.valueOf(value));
                }
            }
        }
        RequestBody body = RequestBody.create(JSON, json.toString());
        return body;
    }

    /**
     * 参数是否合法
     */
    protected boolean paramsEntrySafe(Map.Entry<String, Object> entry) {
        return entry != null
                && !TextUtils.isEmpty(entry.getKey())
                && entry.getValue() != null
                && !TextUtils.isEmpty(entry.getValue().toString());
    }

    private void checkFormMap(Map<String, Object> formMap) {
        if (formMap == null) {
            return;
        }
        for (Map.Entry<String, Object> entry : formMap.entrySet()) {
            if (entry.getValue() instanceof JSONArray) {
                formMap.put(entry.getKey(), ObjectUtils.toJsonArray((JSONArray) entry.getValue()));
            } else if (entry.getValue() instanceof JSONObject) {
                formMap.put(entry.getKey(), ObjectUtils.toJsonObject((JSONObject) entry.getValue()));
            }
        }
    }

    /**
     * 设置请求的ContentType,
     */
    public Params setContentType(MediaType mediaType) {
        this.mediaType = mediaType;
        return this;
    }

    public boolean hasFile() {
        return fileMap != null && !fileMap.isEmpty();
    }

    public HashMap<String, File> getFileMap() {
        return fileMap;
    }

    public HashMap<String, Object> getFormMap() {
        return formMap;
    }

    /**
     * 上传File
     */
    public Params putFile(String key, File file) {
        if (fileMap == null) {
            fileMap = new HashMap<>();
        }
        fileMap.put(key, file);
        return this;
    }

    public Params setFileMap(HashMap<String, File> fileMap) {
        this.fileMap = fileMap;
        return this;
    }

    @Deprecated
    public void putFormJson(String formJson) {
        this.formJson = formJson;
    }

    @Deprecated
    public String getFormJson() {
        return formJson;
    }

    public Params put(String key, String value) {
        if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
            formMap.put(key, value);
        }
        return this;
    }

    public Params put(String key, int v) {
        formMap.put(key, v);
        return this;
    }

    public Params put(String key, long v) {
        formMap.put(key, v);
        return this;
    }

    public Params put(String key, float v) {
        formMap.put(key, v);
        return this;
    }

    public Params put(String key, double v) {
        formMap.put(key, v);
        return this;
    }

    public Params put(String key, boolean v) {
        formMap.put(key, v);
        return this;
    }

    public Params put(String key, char v) {
        formMap.put(key, v);
        return this;
    }

    public Params put(String key, JSONObject v) {
        return put(key, ObjectUtils.toJsonObject(v));
    }

    public Params put(String key, JsonObject v) {
        formMap.put(key, v == null ? new JsonObject() : v);
        return this;
    }

    public Params put(String key, JSONArray v) {
        return put(key, ObjectUtils.toJsonArray(v));
    }

    public Params put(String key, JsonArray v) {
        formMap.put(key, v == null ? new JsonArray() : v);
        return this;
    }

    public Params put(String key, ArrayList<?> v) {
        formMap.put(key, v);
        return this;
    }
}